package me.yushuai.wukong.base.config;

import me.yushuai.wukong.base.utils.SecurityHelper;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.concurrent.*;

/**
 * @author zhoushuai@189.cn
 * @since 2023-09-19
 */
@Aspect
@Component
public class ActionLogAop {

    public static final int CORE_POOL_SIZE = 4;
    public static final int MAXIMUM_POOL_SIZE = 12;
    public static final int KEEP_ALIVE_TIME = 30;
    @Autowired
    private ActionLogWorkerFactory actionLogWorkerFactory;

    private BlockingQueue blockingQueue;

    private Executor executor;

    public ActionLogAop() {
        blockingQueue = new ArrayBlockingQueue(128);
        this.executor = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE_TIME, TimeUnit.MINUTES, blockingQueue);
    }

    @Pointcut("@annotation(me.yushuai.wukong.base.annotation.ActionLog)")
    public void actionLogPointcut() {
    }


    /**
     * 记录操作日志
     *
     * @param joinPoint
     * @return
     * @throws Throwable
     */
    @Around("actionLogPointcut()")
    public Object doInvokeMethod(ProceedingJoinPoint joinPoint) throws Throwable {
        final LocalDateTime beginTime = LocalDateTime.now();
        Object result;
        try {
            result = joinPoint.proceed();
        } catch (Throwable ex) {
            throw ex;
        }

        //3. 记录操作日志
        final ActionLogWorker actionLogWorker = actionLogWorkerFactory.create(joinPoint, beginTime, LocalDateTime.now());
        executor.execute(actionLogWorker);
        return result;
    }


}
